

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/HexoPage/img/favicon.jpeg">
  <link rel="icon" href="/HexoPage/img/favicon.jpeg">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="xiaoaodi">
  <meta name="keywords" content="">
  
    <meta name="description" content="#目录[TOC] 一、javaScript基础总结1、数据类型相关知识点1.1 基本数据类型  String: 任意字符串 Number:任意的数值(整数和浮点数) boolean:undefined null:null –&gt; 使用typeof返回的类型为object undefined: undefined 未定义 symnol :新增 symbol是基本数据类型，对象是 Symbol原始">
<meta property="og:type" content="article">
<meta property="og:title" content="JavaScript学习巩固基础外加进阶(上)底层原理">
<meta property="og:url" content="http://xiao_aodi.gitee.io/hexopage/2022/03/22/JavaScript%E8%BF%9B%E9%98%B6%E5%AD%A6%E4%B9%A0%E7%9A%84%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="~吃椰子灰的胖丁">
<meta property="og:description" content="#目录[TOC] 一、javaScript基础总结1、数据类型相关知识点1.1 基本数据类型  String: 任意字符串 Number:任意的数值(整数和浮点数) boolean:undefined null:null –&gt; 使用typeof返回的类型为object undefined: undefined 未定义 symnol :新增 symbol是基本数据类型，对象是 Symbol原始">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-03-22T14:30:00.000Z">
<meta property="article:modified_time" content="2022-03-22T11:09:30.460Z">
<meta property="article:author" content="xiaoaodi">
<meta name="twitter:card" content="summary_large_image">
  
  
  <title>JavaScript学习巩固基础外加进阶(上)底层原理 - ~吃椰子灰的胖丁</title>

  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css" />


  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css@4/github-markdown.min.css" />
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hint.css@2/hint.min.css" />

  
    
    
      
      <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@10/styles/github-gist.min.css" />
    
  

  
    <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.css" />
  


<!-- 主题依赖的图标库，不要自行修改 -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_ba1fz6golrf.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/HexoPage/css/main.css" />

<!-- 自定义样式保持在最底部 -->


  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    var CONFIG = {"hostname":"xiao_aodi.gitee.io","root":"/HexoPage/","version":"1.8.14","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"right","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"copy_btn":true,"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":false,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/HexoPage/local-search.xml"};
  </script>
  <script  src="/HexoPage/js/utils.js" ></script>
  <script  src="/HexoPage/js/color-schema.js" ></script>
<meta name="generator" content="Hexo 6.1.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/HexoPage/">
      <strong>Xiao_aodi</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>
   
      <!-- 天气网 -->
      


    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/HexoPage/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/HexoPage/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/HexoPage/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/HexoPage/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/HexoPage/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="banner" id="banner" parallax=true
         style="background: url('/HexoPage/img/wallhaven-wqve97.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
          <div class="page-header text-center fade-in-up">
            <span class="h2" id="subtitle" title="JavaScript学习巩固基础外加进阶(上)底层原理">
              
            </span>
            
              <div class="mt-3">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-author" aria-hidden="true"></i>
      xiaoaodi
    </span>
  
  
    <span class="post-meta">
      <i class="iconfont icon-date-fill" aria-hidden="true"></i>
      <time datetime="2022-03-22 22:30" pubdate>
        2022年3月22日 晚上
      </time>
    </span>
  
</div>

<div class="mt-1">
  
    <span class="post-meta mr-2">
      <i class="iconfont icon-chart"></i>
      24k 字
    </span>
  

  
    <span class="post-meta mr-2">
      <i class="iconfont icon-clock-fill"></i>
      
      
      200 分钟
    </span>
  

  
  
    
      <!-- 不蒜子统计文章PV -->
      <span id="busuanzi_container_page_pv" style="display: none">
        <i class="iconfont icon-eye" aria-hidden="true"></i>
        <span id="busuanzi_value_page_pv"></span> 次
      </span>
    
  
</div>

            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div class="py-5" id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">JavaScript学习巩固基础外加进阶(上)底层原理</h1>
            
              <p class="note note-info">
                
                  本文最后更新于：2022年3月22日 晚上
                
              </p>
            
            <div class="markdown-body">
              <h1 id="目录"><a href="#目录" class="headerlink" title="#目录"></a>#目录</h1><p>[TOC]</p>
<h1 id="一、javaScript基础总结"><a href="#一、javaScript基础总结" class="headerlink" title="一、javaScript基础总结"></a>一、javaScript基础总结</h1><h2 id="1、数据类型相关知识点"><a href="#1、数据类型相关知识点" class="headerlink" title="1、数据类型相关知识点"></a>1、数据类型相关知识点</h2><h3 id="1-1-基本数据类型"><a href="#1-1-基本数据类型" class="headerlink" title="1.1 基本数据类型"></a>1.1 基本数据类型</h3><blockquote>
<ol>
<li>String: 任意字符串</li>
<li>Number:任意的数值(整数和浮点数)</li>
<li>boolean:undefined</li>
<li>null:null –&gt; 使用typeof返回的类型为object</li>
<li>undefined: undefined 未定义</li>
<li>symnol :新增 symbol是基本数据类型，对象是 Symbol原始值的封装</li>
<li>bigint: 是一种数字类型的数据，它可以标识任意精度格式的整数</li>
</ol>
</blockquote>
<h3 id="1-2-引用数据类型"><a href="#1-2-引用数据类型" class="headerlink" title="1.2 引用数据类型"></a>1.2 引用数据类型</h3><blockquote>
<ol>
<li>Object: 任意的对象</li>
<li>Function: 一种特别的对象（可以执行） – 内部是可执行的代码块</li>
<li>Array: 特别的对象，是以key为数值下标属性,内部的结构是有序的</li>
</ol>
</blockquote>
<h3 id="1-3-判断的方法"><a href="#1-3-判断的方法" class="headerlink" title="1.3 判断的方法"></a>1.3 判断的方法</h3><h4 id="1-3-1-typeof"><a href="#1-3-1-typeof" class="headerlink" title="1.3.1 typeof"></a>1.3.1 typeof</h4><blockquote>
<p><strong>typeof</strong> 返回的是一个字符串目标是未经计算的操作数的类型</p>
<p>可以判断: undefined、数值、字符串、布尔值、function</p>
<p>不能判断：null和object object和array</p>
<p>代码示例：</p>
<figure class="highlight html"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></div></td><td class="code"><pre><code class="hljs html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">&quot;en&quot;</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">&quot;X-UA-Compatible&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;IE=edge&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;viewport&quot;</span> <span class="hljs-attr">content</span>=<span class="hljs-string">&quot;width=device-width, initial-scale=1.0&quot;</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Document<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript">     <span class="hljs-comment">// typeof返回数据类型的字符串表达</span></span><br><span class="language-javascript">    <span class="hljs-keyword">var</span> obj</span><br><span class="language-javascript">    <span class="hljs-comment">//注意:typeof返回的是字符串</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj, <span class="hljs-keyword">typeof</span> obj, <span class="hljs-keyword">typeof</span> obj === <span class="hljs-string">&#x27;undefined&#x27;</span>,obj === <span class="hljs-literal">undefined</span> )  <span class="hljs-comment">// undefined &#x27;undefined&#x27; true true</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-literal">undefined</span> === <span class="hljs-string">&#x27;undefined&#x27;</span>) <span class="hljs-comment">//false  undefined不是字符串</span></span><br><span class="language-javascript"></span><br><span class="language-javascript">    obj = <span class="hljs-number">40000</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> a===<span class="hljs-string">&#x27;number&#x27;</span>) <span class="hljs-comment">//true</span></span><br><span class="language-javascript"></span><br><span class="language-javascript">    obj = <span class="hljs-string">&#x27;aodi&#x27;</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> obj===<span class="hljs-string">&#x27;string&#x27;</span>) <span class="hljs-comment">//true</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> obj===<span class="hljs-string">&#x27;String&#x27;</span>) <span class="hljs-comment">//false  --&gt;注意,返回的类型为小写</span></span><br><span class="language-javascript">    obj = <span class="hljs-literal">true</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> obj===<span class="hljs-string">&#x27;boolean&#x27;</span>) <span class="hljs-comment">//true</span></span><br><span class="language-javascript">    obj = <span class="hljs-literal">null</span></span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> obj, obj===<span class="hljs-literal">null</span>) <span class="hljs-comment">// &#x27;object&#x27;  true</span></span><br><span class="language-javascript"></span><br><span class="language-javascript">    <span class="hljs-keyword">let</span> b=&#123;&#125;</span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> b,<span class="hljs-keyword">typeof</span> <span class="hljs-literal">null</span>, <span class="hljs-string">&#x27;-------&#x27;</span>) <span class="hljs-comment">// &#x27;object&#x27; &#x27;object&#x27;  --&gt;所以Typeof不能判断null与object</span></span><br><span class="language-javascript">    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span><br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span><br></code></pre></td></tr></table></figure>

<p>注意<code>: 运行</code>console.log(typeof undefined)<code>时,得到的的也是一个</code>字符串,同时为小写 ‘undefined’&#96;</p>
</blockquote>
<h4 id="1-3-2instanceof-判断实例方法"><a href="#1-3-2instanceof-判断实例方法" class="headerlink" title="1.3.2instanceof(判断实例方法)"></a>1.3.2<code>instanceof</code>(判断实例方法)</h4><blockquote>
<p> 专门判断对象&#96;的具体类型</p>
<p><strong><code>instanceof</code></strong> <strong>运算符</strong>用于检测构造函数的 <code>prototype</code> 属性是否出现在某个实例对象的原型链上。</p>
<p>代码示例:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> b1 = &#123;<br>     <span class="hljs-attr">b2</span>: [<span class="hljs-number">1</span>, <span class="hljs-string">&#x27;abc&#x27;</span>, <span class="hljs-variable language_">console</span>.<span class="hljs-property">log</span>],<br>  <span class="hljs-comment">//可以简化成 b3:()=&gt;()=&gt; &#x27;aodi&#x27;  --&gt;高阶函数相关知识</span><br>     <span class="hljs-attr">b3</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<br>       <span class="hljs-keyword">return</span>  <span class="hljs-function">() =&gt;</span>&#123;  <span class="hljs-keyword">return</span>   <span class="hljs-string">&#x27;aodi&#x27;</span>&#125;<br>     &#125;<br>   &#125;<br>  <span class="hljs-comment">/**使用instanceof进行对象判断*/</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b1 <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>, b1 <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>) <span class="hljs-comment">// true  false</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b1.<span class="hljs-property">b2</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Array</span>, b1.<span class="hljs-property">b2</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>) <span class="hljs-comment">// true true</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b1.<span class="hljs-property">b3</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Function</span>, b1.<span class="hljs-property">b3</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>) <span class="hljs-comment">// true true</span><br><br>   <span class="hljs-comment">/**使用typeof进行对象中某属性的判断*/</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> b1.<span class="hljs-property">b2</span>, <span class="hljs-keyword">typeof</span> <span class="hljs-literal">null</span>) <span class="hljs-comment">// &#x27;object&#x27; &#x27;object&#x27;  </span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> b1.<span class="hljs-property">b3</span>===<span class="hljs-string">&#x27;function&#x27;</span>) <span class="hljs-comment">// true</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> b1.<span class="hljs-property">b2</span>[<span class="hljs-number">2</span>]===<span class="hljs-string">&#x27;function&#x27;</span>) <span class="hljs-comment">//true</span><br><br>   <span class="hljs-comment">/**调用对象与数组中某函数示例*/</span><br>   b1.<span class="hljs-property">b2</span>[<span class="hljs-number">2</span>](<span class="hljs-string">&#x27;调用console.log打印hongjilin&#x27;</span>)    <span class="hljs-comment">//调用console.log打印hongjilin</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b1.<span class="hljs-title function_">b3</span>()()) <span class="hljs-comment">// hongjilin</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-3-3"><a href="#1-3-3" class="headerlink" title="1.3.3 ==="></a>1.3.3 <em><code>===</code></em></h4><blockquote>
<p>可以判断: undefined, null</p>
<p>简而言之，在比较两件事情时，<code>双等号将执行类型转换</code>;<code> 三等号将进行相同的比较，而不进行类型转换</code> (如果类型不同, 只是总会返回 false )</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-literal">null</span> === <span class="hljs-literal">undefined</span>);  <span class="hljs-comment">//false</span><br><span class="hljs-keyword">var</span> obj <br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj === <span class="hljs-literal">undefined</span>) <span class="hljs-comment">//true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj === <span class="hljs-literal">null</span>) <span class="hljs-comment">//false</span><br></code></pre></td></tr></table></figure>

<h3 id="1-4-相关问题引出"><a href="#1-4-相关问题引出" class="headerlink" title="1.4 相关问题引出"></a>1.4 相关问题引出</h3><h4 id="1-4-1-undefined与null的区别"><a href="#1-4-1-undefined与null的区别" class="headerlink" title="1.4.1 undefined与null的区别?"></a>1.4.1 undefined与null的区别?</h4><blockquote>
<p>undefined代表定义未赋值</p>
<p>nulll定义并赋值了, 只是值为null</p>
<p>代码示例</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> obj<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj)  <span class="hljs-comment">// undefined</span><br>obj = <span class="hljs-literal">null</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj) <span class="hljs-comment">// null</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-4-2-什么时候给变量赋值为null呢"><a href="#1-4-2-什么时候给变量赋值为null呢" class="headerlink" title="1.4.2 什么时候给变量赋值为null呢?"></a>1.4.2 什么时候给变量赋值为null呢?</h4><blockquote>
<p>初始赋值, 表明将要赋值为对象,<code>可以用做约定俗成的占位符</code></p>
<p>结束前, 让对象成为垃圾对象(被垃圾回收器回收)</p>
<p>代码示例</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> b = <span class="hljs-literal">null</span>  <span class="hljs-comment">// 初始赋值为null, 表明将要赋值为对象</span><br><span class="hljs-comment">//确定对象就赋值</span><br>b = [<span class="hljs-string">&#x27;atguigu&#x27;</span>, <span class="hljs-number">12</span>]<br><span class="hljs-comment">//最后在不使用的时候,将其引用置空,就可以释放b这个对象占用的内存      ---当没有引用指向它的对象称为垃圾对象</span><br>b = <span class="hljs-literal">null</span> <span class="hljs-comment">// 让b指向的对象成为垃圾对象(被垃圾回收器回收)</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h4 id="1-4-3-严格区别变量类型与数据类型"><a href="#1-4-3-严格区别变量类型与数据类型" class="headerlink" title="1.4.3 严格区别变量类型与数据类型?"></a>1.4.3 <em>严格区别变量类型与数据类型?</em></h4><blockquote>
<p>数据的类型</p>
<p>基本类型</p>
<p>对象类型</p>
<p>变量的类型(变量内存值的类型)</p>
<p>基本类型: 保存就是<code>基本类型</code>的数据</p>
<p>引用类型: 保存的是地址值(对象类型)</p>
</blockquote>
<h4 id="1-4-4-字符串对比-gt-、-lt-以及方法"><a href="#1-4-4-字符串对比-gt-、-lt-以及方法" class="headerlink" title="1.4.4 字符串对比*&gt;、&lt;*以及方法"></a>1.4.4 字符串对比*<code>&gt;</code>、<code>&lt;</code>*以及方法</h4><blockquote>
<p>Javascript字符串在进行大于(小于)比较时，会根据第一个不同的字符的ascii值码进行比较，当数字(number)与字符串(string)进行比较大小时，会强制的将数字(number)转换成字符串(string)然后再进行比较</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs js">(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;13&#x27;</span>&gt;<span class="hljs-string">&#x27;3&#x27;</span>); <span class="hljs-comment">// 输出：false</span><br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">5</span>&gt;<span class="hljs-string">&#x27;6&#x27;</span>);  <span class="hljs-comment">// 输出： false</span><br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;d&#x27;</span>&gt;<span class="hljs-string">&#x27;ABDC&#x27;</span>) <span class="hljs-comment">// 输出： true</span><br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">19</span> &gt; <span class="hljs-string">&#x27;ssf&#x27;</span>) <span class="hljs-comment">// 输出 false</span><br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;A&#x27;</span>&gt;<span class="hljs-string">&#x27;abcdef&#x27;</span>) <span class="hljs-comment">// 输出 false</span><br>  &#125;)()<br></code></pre></td></tr></table></figure>
</blockquote>
<h2 id="2、数据-变量-内存的理解"><a href="#2、数据-变量-内存的理解" class="headerlink" title="2、数据,变量, 内存的理解"></a>2、数据,变量, 内存的理解</h2><h3 id="2-1-什么是数据"><a href="#2-1-什么是数据" class="headerlink" title="2.1 什么是数据?"></a>2.1 什么是数据?</h3><blockquote>
<ol>
<li><p>存储在内存中代表特定信息的’东西’, 本质上是0101…</p>
</li>
<li><p>数据的特点: <code>可传递</code>, <code>可运算</code>    –&gt;let a&#x3D;0;b&#x3D;a 体现可传递</p>
</li>
<li><p>一切皆数据</p>
</li>
<li><p>内存中所有操作的目标: 数据   对数据进行算术运算、逻辑运算、赋值、运行函数</p>
</li>
</ol>
</blockquote>
<h3 id="2-2-什么是内存"><a href="#2-2-什么是内存" class="headerlink" title="2.2 什么是内存?"></a>2.2 什么是内存?</h3><blockquote>
<ol>
<li>内存条通电后产生的可储存数据的空间(临时的)</li>
<li>内存产生和死亡: 内存条(电路版)&#x3D;&#x3D;&gt;通电&#x3D;&#x3D;&gt;产生内存空间&#x3D;&#x3D;&gt;存储数据&#x3D;&#x3D;&gt;处理数据&#x3D;&#x3D;&gt;断电&#x3D;&#x3D;&gt;内存空间和数据都消失</li>
<li>一块小内存的2个数据：地址值和内部存储的数据</li>
<li>内存分类：栈: 全局变量&#x2F;局部变量  堆: 对象</li>
</ol>
</blockquote>
<h3 id="2-3-什么是变量"><a href="#2-3-什么是变量" class="headerlink" title="2.3 什么是变量?"></a>2.3 什么是变量?</h3><blockquote>
<p>可变化的量, 由变量名和变量值组成</p>
<p>每个变量都对应的一块小内存, 变量名用来查找对应的内存, 变量值就是内存中保存的数据</p>
<p>ps:变量<code>obj.xx</code>–&gt;<code>.</code>相当于拿着地址找到后面对应的内存,所以只有当我变量中存的是地址,才可以用<code>.</code></p>
</blockquote>
<h3 id="2-4-内存-数据-变量三者之间的关系"><a href="#2-4-内存-数据-变量三者之间的关系" class="headerlink" title="2.4 内存,数据, 变量三者之间的关系"></a>2.4 内存,数据, 变量三者之间的关系</h3><blockquote>
<p>内存用来存储数据的空间, 变量是内存的标识</p>
</blockquote>
<h3 id="2-5-相关问题引出"><a href="#2-5-相关问题引出" class="headerlink" title="2.5 相关问题引出"></a>2.5 相关问题引出</h3><h4 id="2-5-1-关于赋值和内存的问题"><a href="#2-5-1-关于赋值和内存的问题" class="headerlink" title="2.5.1 关于赋值和内存的问题"></a>2.5.1 <em>关于赋值和内存的问题</em></h4><blockquote>
<p>let a &#x3D; xxx, a内存中到底保存的是什么?</p>
<p>xxx是基本数据, 保存的就是这个数据</p>
<p>xxx是对象, 保存的是对象的地址值</p>
<p>xxx是一个变量, 保存的xxx的内存内容(可能是基本数据, 也可能是地址值)</p>
</blockquote>
<h4 id="2-5-2-关于引用变量赋值问题"><a href="#2-5-2-关于引用变量赋值问题" class="headerlink" title="2.5.2 关于引用变量赋值问题"></a>2.5.2 <em>关于引用变量赋值问题</em></h4><blockquote>
<p>2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据</p>
<p>2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">let</span> a = &#123;<span class="hljs-attr">age</span>: <span class="hljs-number">12</span>&#125;<br> <span class="hljs-comment">//此时是将a指向的地址值赋值给B,所以B此时也指向&#123;age:12&#125;这个内存</span><br><span class="hljs-keyword">let</span> b = a<br><span class="hljs-comment">//此时重新创建了一个内存并让a指向它,所以此处a指向的是&#123;name:&#x27;hong&#x27;&#125;,而b指向仍是刚开始的指向&#123;age:12&#125;</span><br>a = &#123;<span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;aodi&#x27;</span>&#125;<br><span class="hljs-comment">//此时a与b指向的内存已经不一样了,所以修改互不影响</span><br>b.<span class="hljs-property">age</span> = <span class="hljs-number">14</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b.<span class="hljs-property">age</span>, a.<span class="hljs-property">name</span>, a.<span class="hljs-property">age</span>) <span class="hljs-comment">// 14 aodi undefined</span><br><br><span class="hljs-comment">//2个引用变量指向同一个对象, 让其中一个引用变量指向另一个对象, 另一引用变量依然指向前一个对象   --&gt;所以 a 仍是  &#123;name: &#x27;hong&#x27;&#125;</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">fn2</span>=(<span class="hljs-params">obj</span>) =&gt; obj = &#123;<span class="hljs-attr">age</span>: <span class="hljs-number">15</span>&#125;<br><span class="hljs-title function_">fn2</span>(a)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">age</span>) <span class="hljs-comment">//undefined </span><br></code></pre></td></tr></table></figure>
</blockquote>
<h4 id="2-5-3-在js调用函数时传递变量参数时-是值传递还是引用传递"><a href="#2-5-3-在js调用函数时传递变量参数时-是值传递还是引用传递" class="headerlink" title="2.5.3  在js调用函数时传递变量参数时, 是值传递还是引用传递"></a>2.5.3  <em>在js调用函数时传递变量参数时, 是值传递还是引用传递</em></h4><blockquote>
<p>理解1: 都是值(基本&#x2F;地址值)传递</p>
<p>所以实际上传进function中的参数也是拿着其存着的地址值找内存</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//传进来的obj存储的是a中存的地址值,所以obj==a(因为他们地址值一致,指向一致)</span><br><span class="hljs-comment">//2个引用变量指向同一个对象, 通过一个变量修改对象内部数据, 另一个变量看到的是修改之后的数据  --&gt;所以被进行了修改</span><br>  <span class="hljs-keyword">let</span> a = &#123;<span class="hljs-attr">name</span>: <span class="hljs-string">&#x27;hong&#x27;</span>&#125;<br>  <span class="hljs-keyword">const</span> <span class="hljs-title function_">fn2</span>=(<span class="hljs-params">obj</span>) =&gt; obj.<span class="hljs-property">age</span>= <span class="hljs-number">15</span><br>  <span class="hljs-title function_">fn2</span>(a)<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a.<span class="hljs-property">age</span>) <span class="hljs-comment">//15</span><br></code></pre></td></tr></table></figure>

<p>理解2: 可能是值传递, 也可能是引用传递(地址值)</p>
</blockquote>
<h4 id="2-5-4-JS引擎如何管理内存"><a href="#2-5-4-JS引擎如何管理内存" class="headerlink" title="2.5.4 JS引擎如何管理内存?"></a>2.5.4 <em>JS引擎如何管理内存?</em></h4><blockquote>
<ol>
<li><p>内存生命周期 : 分配小内存空间, 得到它的使用权 ,存储数据, 可以反复进行操作 释放小内存空间</p>
</li>
<li><p>释放内存 : 局部变量: 函数执行完自动释放 对象: 成为垃圾对象&#x3D;&#x3D;&gt;垃圾回收器回收</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span><br><span class="hljs-keyword">var</span> obj = &#123;<span class="hljs-attr">name</span>:<span class="hljs-string">&quot;hong&quot;</span>&#125;<br>obj = <span class="hljs-literal">undefined</span> ||<span class="hljs-literal">null</span>  <span class="hljs-comment">//此时,obj没有被释放,但是之前声明的`&#123;name:&quot;hong&quot;&#125;`由于没有人指向它,会在后面你某个时刻被垃圾回收器回收</span><br>   <br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span> () &#123; <span class="hljs-keyword">var</span> b = &#123;&#125;&#125;<br><span class="hljs-title function_">fn</span>() <span class="hljs-comment">// b是自动释放, b所指向的对象是在后面的某个时刻由垃圾回收器回收</span><br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h2 id="3、对象"><a href="#3、对象" class="headerlink" title="3、对象"></a>3、对象</h2><h3 id="3-1-对象的概念"><a href="#3-1-对象的概念" class="headerlink" title="3.1 对象的概念"></a>3.1 对象的概念</h3><h4 id="3-1-1-什么是对象"><a href="#3-1-1-什么是对象" class="headerlink" title="3.1.1 什么是对象?"></a>3.1.1 什么是对象?</h4><blockquote>
<p>多个数据的封装体</p>
<p>用来保存多个数据的容器</p>
<p>一个对象代表现实中的一个事物</p>
</blockquote>
<h4 id="3-1-2-为什么要用对象"><a href="#3-1-2-为什么要用对象" class="headerlink" title="3.1.2 为什么要用对象?"></a>3.1.2 为什么要用对象?</h4><blockquote>
<p>统一管理多个数据</p>
</blockquote>
<h4 id="3-1-3-对象的组成"><a href="#3-1-3-对象的组成" class="headerlink" title="3.1.3 对象的组成"></a>3.1.3 对象的组成</h4><blockquote>
<p>属性: 属性名(字符串)和属性值(任意)组成</p>
<p>方法: 一种特别的属性(属性值是函数)</p>
</blockquote>
<h3 id="3-2-如何访问对象内部数据"><a href="#3-2-如何访问对象内部数据" class="headerlink" title="3.2 如何访问对象内部数据?"></a>3.2 如何访问对象内部数据?</h3><blockquote>
<p><code>.属性名</code>: 编码简单, 有时不能用</p>
<p><code>[&#39;属性名&#39;]</code>: 编码麻烦, 能通用</p>
</blockquote>
<h3 id="3-3-什么时候必须使用-39-属性名-39-的方式"><a href="#3-3-什么时候必须使用-39-属性名-39-的方式" class="headerlink" title="3.3 什么时候必须使用[&#39;属性名&#39;]的方式?"></a>3.3 什么时候必须使用<code>[&#39;属性名&#39;]</code>的方式?</h3><blockquote>
<ol>
<li><p>属性名包含特殊字符: <code>-</code> <code>空格</code></p>
</li>
<li><p>属性名不确定</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> p = &#123;&#125;<br><span class="hljs-comment">//1. 给p对象添加一个属性: content type: text/json</span><br><span class="hljs-comment">// p.content-type = &#x27;text/json&#x27; //不能用</span><br>p[<span class="hljs-string">&#x27;content-type&#x27;</span>] = <span class="hljs-string">&#x27;text/json&#x27;</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p[<span class="hljs-string">&#x27;content-type&#x27;</span>])<br>   <br><span class="hljs-comment">//2. 属性名不确定</span><br><span class="hljs-keyword">var</span> propName = <span class="hljs-string">&#x27;myAge&#x27;</span><br><span class="hljs-keyword">var</span> value = <span class="hljs-number">18</span><br><span class="hljs-comment">// p.propName = value //不能用</span><br>p[propName] = value<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p[propName])<br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h2 id="4、函数"><a href="#4、函数" class="headerlink" title="4、函数"></a>4、函数</h2><h3 id="4-1函数的概念"><a href="#4-1函数的概念" class="headerlink" title="4.1函数的概念"></a>4.1函数的概念</h3><h4 id="4-1-1-什么是函数"><a href="#4-1-1-什么是函数" class="headerlink" title="4.1.1  什么是函数"></a>4.1.1  <em>什么是函数</em></h4><blockquote>
<p>实现特定功能的n条语句的封装体</p>
<p>只有函数是可以执行的, 其它类型的数据不能执行</p>
</blockquote>
<h4 id="4-1-1-为什么要用函数"><a href="#4-1-1-为什么要用函数" class="headerlink" title="4.1.1  为什么要用函数?"></a>4.1.1  <em>为什么要用函数?</em></h4><blockquote>
<p>提高代码复用</p>
<p>便于阅读交流</p>
</blockquote>
<h4 id="4-1-1-如何定义函数"><a href="#4-1-1-如何定义函数" class="headerlink" title="4.1.1  如何定义函数?"></a>4.1.1  <em>如何定义函数?</em></h4><blockquote>
<p>函数声明</p>
<p>表达式</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn1</span> () &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fn1()&#x27;</span> )<span class="hljs-comment">//函数声明</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">fn2</span> = (<span class="hljs-params"></span>)=&gt; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fn2()&#x27;</span>)  <span class="hljs-comment">//表达式js</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="4-2-如何调用-执行-函数"><a href="#4-2-如何调用-执行-函数" class="headerlink" title="4.2 如何调用(执行)函数"></a>4.2 如何调用(执行)函数</h3><blockquote>
<ol>
<li><p>test(): 直接调用</p>
</li>
<li><p>obj.test(): 通过对象调用</p>
</li>
<li><p>new test(): new调用</p>
</li>
<li><p><code>test.call/apply(obj)</code>: 临时让test成为obj的方法进行调用</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> obj = &#123;&#125;<br><span class="hljs-comment">//此处不能使用箭头函数,因为箭头函数会改变this指向</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">test2</span> () &#123;<br>  <span class="hljs-variable language_">this</span>.<span class="hljs-property">xxx</span> = <span class="hljs-string">&#x27;hongjilin&#x27;</span><br>&#125;<br><span class="hljs-comment">// obj.test2()  不能直接, 根本就没有</span><br>test2.<span class="hljs-title function_">call</span>(obj)  <span class="hljs-comment">// 可以让一个函数成为指定任意对象的方法进行调用</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(obj.<span class="hljs-property">xxx</span>)<br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h3 id="4-3-回调函数"><a href="#4-3-回调函数" class="headerlink" title="4.3 回调函数"></a>4.3 回调函数</h3><h4 id="4-3-1-什么函数才是回调函数"><a href="#4-3-1-什么函数才是回调函数" class="headerlink" title="4.3.1 什么函数才是回调函数?"></a><em>4.3.1 什么函数才是回调函数?</em></h4><blockquote>
<p>你定义的    你没有调 但最终它执行了(在某个时刻或某个条件下)</p>
</blockquote>
<h4 id="4-3-1-常见的回调函数"><a href="#4-3-1-常见的回调函数" class="headerlink" title="4.3.1 常见的回调函数?"></a><em>4.3.1 常见的回调函数?</em></h4><blockquote>
<ol>
<li><p>dom事件回调函数 &#x3D;&#x3D;&gt;发生事件的dom元素</p>
</li>
<li><p>定时器回调函数 &#x3D;&#x3D;&#x3D;&gt;window</p>
</li>
<li><p>ajax请求回调函数(后面讲)</p>
</li>
<li><p>生命周期回调函数(后面讲)</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs js"> / dom事件回调函数<br><span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;btn&#x27;</span>).<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<span class="hljs-title function_">alert</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">innerHTML</span>)&#125;<br><span class="hljs-comment">// 定时器回调函数</span><br><span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;   <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;到点了&#x27;</span>+<span class="hljs-variable language_">this</span>)&#125;, <span class="hljs-number">2000</span>)<br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h3 id="4-4-IIFE-自调用函数"><a href="#4-4-IIFE-自调用函数" class="headerlink" title="4.4 IIFE (自调用函数)"></a>4.4 IIFE (自调用函数)</h3><blockquote>
<p>全称: <code>Immediately-Invoked Function Expression</code> 自调用函数</p>
<p>作用: 隐藏实现 不会污染外部(一般指全局)命名空间 用它来编码js模块</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs js">(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123; <span class="hljs-comment">//匿名函数自调用</span><br>    <span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a + <span class="hljs-number">3</span>)<br>   &#125;)()<br><br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a) <span class="hljs-comment">// a is not defined</span><br><br>  <span class="hljs-comment">//此处前方为何要一个`;`--&gt;因为自调用函数外部有一个()包裹,可能与前方以()结尾的代码被一起认为是函数调用</span><br>  <span class="hljs-comment">//不加分号可能会被认为这样 console.log(a)(IIFE)</span><br>  ;(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<span class="hljs-comment">//不会污染外部(全局)命名空间--&gt;举例</span><br>    <span class="hljs-keyword">let</span> a = <span class="hljs-number">1</span>;<br>    <span class="hljs-keyword">function</span> <span class="hljs-title function_">test</span> () &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(++a) &#125; <span class="hljs-comment">//声明一个局部函数test</span><br>    <span class="hljs-variable language_">window</span>.<span class="hljs-property">$</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;  <span class="hljs-keyword">return</span> &#123;<span class="hljs-attr">test</span>: test&#125; &#125;<span class="hljs-comment">// 向外暴露一个全局函数</span><br>  &#125;)()<br>  test ()  <span class="hljs-comment">//test is not defined</span><br>  $().<span class="hljs-title function_">test</span>() <span class="hljs-comment">// 1. $是一个函数 2. $执行后返回的是一个对象</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="4-5-函数中的this"><a href="#4-5-函数中的this" class="headerlink" title="4.5 函数中的this"></a>4.5 函数中的this</h3><h4 id="4-5-1-this是什么"><a href="#4-5-1-this是什么" class="headerlink" title="4.5.1 this是什么?"></a>4.5.1 <em>this是什么?</em></h4><blockquote>
<p>任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window</p>
<p>所有函数内部都有一个变量this</p>
<p>它的值是<code>调用函数的当前对象</code></p>
</blockquote>
<h4 id="4-5-2-如何确定this的值"><a href="#4-5-2-如何确定this的值" class="headerlink" title="4.5.2 如何确定this的值?"></a>4.5.2 如何确定this的值?</h4><blockquote>
<p>test(): window</p>
<p>p.test(): p</p>
<p>new test(): 新创建的对象</p>
<p>p.call(obj): obj</p>
</blockquote>
<h4 id="4-5-3-代码举例详解"><a href="#4-5-3-代码举例详解" class="headerlink" title="4.5.3 代码举例详解"></a>4.5.3 代码举例详解</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">Person</span>(<span class="hljs-params">color</span>) &#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>)<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">color</span> = color;<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">getColor</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">color</span>;<br>&#125;;<br><span class="hljs-variable language_">this</span>.<span class="hljs-property">setColor</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">color</span>) &#123;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>)<br> <span class="hljs-variable language_">this</span>.<span class="hljs-property">color</span> = color;<br>&#125;;<br>&#125;<br><br><span class="hljs-title class_">Person</span>(<span class="hljs-string">&quot;red&quot;</span>); <span class="hljs-comment">//this是谁? window</span><br><br><span class="hljs-keyword">const</span> p = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">&quot;yello&quot;</span>); <span class="hljs-comment">//this是谁? p</span><br><br>p.<span class="hljs-title function_">getColor</span>(); <span class="hljs-comment">//this是谁? p</span><br><br><span class="hljs-keyword">const</span> obj = &#123;&#125;;<br><span class="hljs-comment">//调用call会改变this指向--&gt;让我的p函数成为`obj`的临时方法进行调用</span><br>p.<span class="hljs-property">setColor</span>.<span class="hljs-title function_">call</span>(obj, <span class="hljs-string">&quot;black&quot;</span>); <span class="hljs-comment">//this是谁? obj</span><br><br><span class="hljs-keyword">const</span> test = p.<span class="hljs-property">setColor</span>;<br><span class="hljs-title function_">test</span>(); <span class="hljs-comment">//this是谁? window  --&gt;因为直接调用了</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fun1</span>(<span class="hljs-params"></span>) &#123;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fun2</span>(<span class="hljs-params"></span>) &#123;  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-variable language_">this</span>); &#125;<br><span class="hljs-title function_">fun2</span>(); <span class="hljs-comment">//this是谁? window</span><br>&#125;<br><span class="hljs-title function_">fun1</span>();<span class="hljs-comment">//调用fun1</span><br></code></pre></td></tr></table></figure>

<h3 id="4-6-关于语句分号"><a href="#4-6-关于语句分号" class="headerlink" title="4.6 关于语句分号"></a>4.6 关于语句分号</h3><blockquote>
<ol>
<li><p>js一条语句的后面可以不加分号</p>
</li>
<li><p>是否加分号是编码风格问题, 没有应该不应该，只有你自己喜欢不喜欢</p>
</li>
<li><p>在下面2种情况下不加分号会有问题:小括号开头的前一条语句 ,  中方括号开头的前一条语句</p>
</li>
<li><p>解决办法: 在行首加分号</p>
</li>
<li><p>强有力的例子: vue.js库</p>
</li>
</ol>
</blockquote>
<h1 id="二、函数高级"><a href="#二、函数高级" class="headerlink" title="二、函数高级"></a>二、函数高级</h1><h2 id="1-原型与原型链"><a href="#1-原型与原型链" class="headerlink" title="1. 原型与原型链"></a>1. 原型与原型链</h2><h3 id="1-1原型-prototype"><a href="#1-1原型-prototype" class="headerlink" title="1.1原型 [prototype]"></a>1.1原型 [prototype]</h3><blockquote>
<p>1.函数的<code>prototype</code>属性</p>
<p>每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)</p>
<p>原型对象中有一个属性constructor, 它指向函数对象</p>
<p>2.给原型对象添加属性(<code>一般都是方法</code>)</p>
<p>作用: 函数的所有实例对象自动拥有原型中的属性(方法)</p>
<p>3.代码示例</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs js"><br><span class="hljs-comment">// 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Date</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-keyword">typeof</span> <span class="hljs-title class_">Date</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Fun</span> () &#123; &#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Fun</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)  <span class="hljs-comment">// 默认指向一个Object空对象(没有我们的属性)</span><br><br><span class="hljs-comment">// 原型对象中有一个属性constructor, 它指向函数对象</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Date</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">constructor</span>===<span class="hljs-title class_">Date</span>)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Fun</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">constructor</span>===<span class="hljs-title class_">Fun</span>)<br><br><span class="hljs-comment">//给原型对象添加属性(一般是方法) ===&gt;实例对象可以访问</span><br><span class="hljs-title class_">Fun</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">test</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;test()&#x27;</span>) &#125;<br><span class="hljs-keyword">var</span> fun = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Fun</span>()<br>fun.<span class="hljs-title function_">test</span>()<br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="1-2-显式原型与隐式原型"><a href="#1-2-显式原型与隐式原型" class="headerlink" title="1.2 显式原型与隐式原型"></a>1.2 显式原型与隐式原型</h3><blockquote>
<ol>
<li><p>每个函数function都有一个<code>prototype</code>，即<code>显式</code>原型(属性)</p>
</li>
<li><p>每个实例对象都有一个[<code>__ proto __</code>]，可称为<code>隐式</code>原型(属性)</p>
</li>
<li><p>对象的隐式原型的值为其对应构造函数的显式原型的值</p>
<p>总结: </p>
<p>1&gt; 函数的[<code>prototype</code>]属性: 在定义函数时自动添加的, 默认值是一个空Object对象</p>
<p>2&gt; 对象的[<code>__ proto __</code>]属性: 创建对象时自动添加的, <code>默认值为构造函数的prototype属性值</code></p>
<p>3&gt; 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//定义构造函数</span><br>   <span class="hljs-keyword">function</span> <span class="hljs-title function_">Fn</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 内部默认执行语句: this.prototype = &#123;&#125;</span><br>     &#125;<br>   <span class="hljs-comment">// 1. 每个函数function都有一个prototype，即显式原型属性, 默认指向一个空的Object对象</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Fn</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br>   <span class="hljs-comment">// 2. 每个实例对象都有一个__proto__，可称为隐式原型</span><br>   <span class="hljs-comment">//创建实例对象</span><br>   <span class="hljs-keyword">var</span> fn = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Fn</span>()  <span class="hljs-comment">// 内部默认执行语句: this.__proto__ = Fn.prototype</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(fn.<span class="hljs-property">__proto__</span>)<br>   <span class="hljs-comment">// 3. 对象的隐式原型的值为其对应构造函数的显式原型的值</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Fn</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>===fn.<span class="hljs-property">__proto__</span>) <span class="hljs-comment">// true</span><br>   <span class="hljs-comment">//给原型添加方法</span><br>   <span class="hljs-title class_">Fn</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">test</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<br>     <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;test()&#x27;</span>)<br>   &#125;<br>   <span class="hljs-comment">//通过实例调用原型的方法</span><br>   fn.<span class="hljs-title function_">test</span>()<br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h3 id="1-3-原型链"><a href="#1-3-原型链" class="headerlink" title="1.3 原型链"></a>1.3 原型链</h3><h4 id="1-3-1原型链"><a href="#1-3-1原型链" class="headerlink" title="1.3.1原型链"></a>1.3.1原型链</h4><blockquote>
<p>访问一个对象的属性时:先在自身属性中查找，找到返回, 如果没有, 再沿着[<code>__ proto __</code>]这条链向上查找, 找到返回, 如果最终没找到, 返回undefined</p>
<p>别名: 隐式原型链</p>
<p>作用: 查找对象的属性(方法)</p>
</blockquote>
<h4 id="1-3-2-属性问题"><a href="#1-3-2-属性问题" class="headerlink" title="1.3.2  属性问题"></a>1.3.2  <em>属性问题</em></h4><blockquote>
<p>读取对象的属性值时: 会自动到原型链中查找</p>
<p>设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值</p>
<p>方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">Fn</span>(<span class="hljs-params"></span>) &#123; &#125;<br>   <span class="hljs-title class_">Fn</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">a</span> = <span class="hljs-string">&#x27;xxx&#x27;</span><br>   <span class="hljs-keyword">var</span> fn1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Fn</span>()<br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(fn1.<span class="hljs-property">a</span>, fn1) <span class="hljs-comment">//xxx Fn&#123;&#125;</span><br><br>   <span class="hljs-keyword">var</span> fn2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Fn</span>()<br>   fn2.<span class="hljs-property">a</span> = <span class="hljs-string">&#x27;yyy&#x27;</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(fn1.<span class="hljs-property">a</span>, fn2.<span class="hljs-property">a</span>, fn2) <span class="hljs-comment">//xxx yyy  Fn&#123;a: &quot;yyy&quot;&#125;</span><br><br>   <span class="hljs-keyword">function</span> <span class="hljs-title function_">Person</span>(<span class="hljs-params">name, age</span>) &#123;<br>     <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name<br>     <span class="hljs-variable language_">this</span>.<span class="hljs-property">age</span> = age<br>   &#125;<br>   <span class="hljs-title class_">Person</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">setName</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params">name</span>) &#123;<br>     <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span> = name<br>   &#125;<br>   <span class="hljs-keyword">var</span> p1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">&#x27;Tom&#x27;</span>, <span class="hljs-number">12</span>)<br>   p1.<span class="hljs-title function_">setName</span>(<span class="hljs-string">&#x27;Bob&#x27;</span>)<br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1)  <span class="hljs-comment">//Person &#123;name: &quot;Bob&quot;, age: 12&#125;</span><br><br>   <span class="hljs-keyword">var</span> p2 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Person</span>(<span class="hljs-string">&#x27;Jack&#x27;</span>, <span class="hljs-number">12</span>)<br>   p2.<span class="hljs-title function_">setName</span>(<span class="hljs-string">&#x27;Cat&#x27;</span>)<br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p2) <span class="hljs-comment">//Person &#123;name: &quot;Cat&quot;, age: 12&#125;</span><br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(p1.<span class="hljs-property">__proto__</span>===p2.<span class="hljs-property">__proto__</span>) <span class="hljs-comment">// true   --&gt;所以方法一般定义在原型中</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="1-4-instanceof"><a href="#1-4-instanceof" class="headerlink" title="1.4 instanceof"></a>1.4 instanceof</h3><blockquote>
<ol>
<li><p>instanceof是如何判断的?</p>
<p>表达式: A instanceof B</p>
<p>如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*</span><br><span class="hljs-comment">案例1</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Foo</span>(<span class="hljs-params"></span>) &#123;  &#125;<br><span class="hljs-keyword">var</span> f1 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Foo</span>()<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(f1 <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Foo</span>) <span class="hljs-comment">// true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(f1 <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>) <span class="hljs-comment">// true</span><br>   <br><span class="hljs-comment">/*</span><br><span class="hljs-comment">案例2</span><br><span class="hljs-comment"> */</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Object</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Function</span>) <span class="hljs-comment">// true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Object</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>) <span class="hljs-comment">// true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Function</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Function</span>) <span class="hljs-comment">// true</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Function</span> <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Object</span>) <span class="hljs-comment">// true</span><br>   <br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Foo</span>(<span class="hljs-params"></span>) &#123;&#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Object</span> <span class="hljs-keyword">instanceof</span>  <span class="hljs-title class_">Foo</span>) <span class="hljs-comment">// false</span><br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h3 id="1-5-相关的问题"><a href="#1-5-相关的问题" class="headerlink" title="1.5 相关的问题"></a>1.5 相关的问题</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*</span><br><span class="hljs-comment">测试题1</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">A</span> () &#123;&#125;<br>A.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">n</span> = <span class="hljs-number">1</span><br><span class="hljs-keyword">let</span> b = <span class="hljs-keyword">new</span> <span class="hljs-title function_">A</span>()<br>A.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = &#123; <span class="hljs-attr">n</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">m</span>: <span class="hljs-number">3</span>&#125;<br><span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> <span class="hljs-title function_">A</span>()<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b.<span class="hljs-property">n</span>, b.<span class="hljs-property">m</span>, c.<span class="hljs-property">n</span>, c.<span class="hljs-property">m</span>) <span class="hljs-comment">// 1 undefined 2 3</span><br></code></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*</span><br><span class="hljs-comment">测试题2</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">F</span> ()&#123;&#125;<br><span class="hljs-title class_">Object</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">a</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;a()&#x27;</span>)<br>&#125;<br><span class="hljs-title class_">Function</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">b</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;b()&#x27;</span>)<br>&#125;<br><br><span class="hljs-keyword">let</span> f = <span class="hljs-keyword">new</span> <span class="hljs-title function_">F</span>()<br>f.<span class="hljs-title function_">a</span>() <span class="hljs-comment">//a()</span><br>f.<span class="hljs-title function_">b</span>() <span class="hljs-comment">//f.b is not a function --&gt;找不到</span><br>F.<span class="hljs-title function_">a</span>() <span class="hljs-comment">//a()</span><br>F.<span class="hljs-title function_">b</span>() <span class="hljs-comment">//b()</span><br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(f)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Object</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-title class_">Function</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>)<br></code></pre></td></tr></table></figure>

<h2 id="2-执行上下文与执行上下文栈"><a href="#2-执行上下文与执行上下文栈" class="headerlink" title="2. 执行上下文与执行上下文栈"></a>2. 执行上下文与执行上下文栈</h2><blockquote>
<p>当代码在 JavaScript 中运行时，执行代码的环境非常重要，并将概括为以下几点：</p>
<p><strong>全局代码</strong>——第一次执行代码的默认环境。</p>
<p><strong>函数代码</strong>——当执行流进入函数体时。</p>
<p>(…) —— 我们当作 执行上下文 是当前代码执行的一个环境与范围。</p>
</blockquote>
<blockquote>
<p>换句话说，当我们启动程序时，我们从全局执行上下文中开始。一些变量是在全局执行上下文中声明的。我们称之为全局变量。当程序调用一个函数时，会发生什么?</p>
<p>以下几个步骤：</p>
<ol>
<li><p>JavaScript 创建一个新的执行上下文，我们叫作本地执行上下文。</p>
</li>
<li><p>这个本地执行上下文将有它自己的一组变量，这些变量将是这个执行上下文的本地变量。</p>
</li>
<li><p>新的执行上下文被推到到执行堆栈中。可以将执行堆栈看作是一种保存程序在其执行中的位置的容器。</p>
</li>
</ol>
</blockquote>
<blockquote>
<p>函数什么时候结束? 当它遇到一个 return 语句或一个结束括号}。</p>
</blockquote>
<blockquote>
<p>当一个函数结束时，会发生以下情况:</p>
<ol>
<li><p>这个本地执行上下文从执行堆栈中弹出。</p>
</li>
<li><p>函数将返回值返回调用上下文。调用上下文是调用这个本地的执行上下文，它可以是全局执行上下文，也可以是另外一个本地的执行上下文。这取决于调用执行上下文来处理此时的返回值，返回的值可以是一个对象、一个数组、一个函数、一个布尔值等等，如果函数没有 return 语句，则返回 undefined。</p>
</li>
<li><p>这个本地执行上下文被销毁，销毁是很重要，这个本地执行上下文中声明的所有变量都将被删除，不在有变量，这个就是为什么 称为本地执行上下文中自有的变量。</p>
</li>
</ol>
</blockquote>
<h3 id="2-1-变量提升与函数提升"><a href="#2-1-变量提升与函数提升" class="headerlink" title="2.1 变量提升与函数提升"></a>2.1 变量提升与函数提升</h3><blockquote>
<ol>
<li><p>变量声明提升 :通过var定义(声明)的变量, 在定义语句之前就可以访问到,   值: undefined</p>
</li>
<li><p>函数声明提升:  通过function声明的函数, 在之前就可以直接调用 值: 函数定义(对象)</p>
</li>
<li><p>引出一个问题: 变量提升和函数提升是如何产生的?</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*</span><br><span class="hljs-comment"> 面试题 : 输出 undefined</span><br><span class="hljs-comment">  */</span><br> <span class="hljs-keyword">var</span> a = <span class="hljs-number">3</span><br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span> () &#123;<br>   <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a)<br>   <span class="hljs-keyword">var</span> a = <span class="hljs-number">4</span> <span class="hljs-comment">//变量提升</span><br> &#125;<br> <span class="hljs-title function_">fn</span>()  <span class="hljs-comment">//undefined</span><br><span class="hljs-string">&#x27;--------------------------------------------&#x27;</span><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b) <span class="hljs-comment">//undefined  变量提升</span><br> <span class="hljs-title function_">fn2</span>() <span class="hljs-comment">//可调用  函数提升</span><br> <span class="hljs-comment">// fn3() //不能  变量提升</span><br> <span class="hljs-keyword">var</span> b = <span class="hljs-number">3</span><br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fn2</span>(<span class="hljs-params"></span>) &#123;  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fn2()&#x27;</span>) &#125;<br> <span class="hljs-keyword">var</span> fn3 = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fn3()&#x27;</span>) &#125;<br></code></pre></td></tr></table></figure></li>
</ol>
</blockquote>
<h3 id="2-2-执行上下文"><a href="#2-2-执行上下文" class="headerlink" title="2.2 执行上下文"></a>2.2 执行上下文</h3><blockquote>
<ol>
<li><p>代码分类(位置) : 全局代码  函数(局部)代码</p>
</li>
<li><p>全局执行上下文:  在执行全局代码前将window确定为全局执行上下文  对全局数据进行预处理</p>
<p>var定义的全局变量&#x3D;&#x3D;&gt;undefined, 添加为window的属性</p>
<p>function声明的全局函数&#x3D;&#x3D;&gt;赋值(fun), 添加为window的方法</p>
<p>this&#x3D;&#x3D;&gt;赋值(window)</p>
<p>开始执行全局代码</p>
</li>
</ol>
</blockquote>
<blockquote>
<ol start="3">
<li><p>函数执行上下文</p>
<p>在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象(虚拟的, 存在于栈中)</p>
<p>对局部数据进行预处理: 1&gt;形参变量&#x3D;&#x3D;&gt;赋值(实参)&#x3D;&#x3D;&gt;添加为执行上下文的属性</p>
<p>2&gt;<code>arguments</code>&#x3D;&#x3D;&gt;赋值(实参列表), 添加为执行上下文的属性</p>
<p>3&gt;var定义的局部变量&#x3D;&#x3D;&gt;undefined, 添加为执行上下文的属性</p>
<p>4&gt; function声明的函数 &#x3D;&#x3D;&gt;赋值(fun), 添加为执行上下文的方法</p>
<p>5&gt;this&#x3D;&#x3D;&gt;赋值(调用函数的对象)</p>
<p>开始执行函数体代码</p>
</li>
</ol>
</blockquote>
<h3 id="2-3-执行上下文栈"><a href="#2-3-执行上下文栈" class="headerlink" title="2.3 执行上下文栈"></a>2.3 执行上下文栈</h3><blockquote>
<ol>
<li>在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象</li>
<li>在全局执行上下文(window)确定后, 将其添加到栈中(压栈)–&gt;<code>所以栈底百分百是[window]</code></li>
<li>在函数执行上下文创建后, 将其添加到栈中(压栈)</li>
<li>在当前函数执行完后,将栈顶的对象移除(出栈)</li>
<li>当所有的代码执行完后, 栈中只剩下window</li>
<li>上下文栈数&#x3D;&#x3D;函数调用数+1</li>
</ol>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//1. 进入全局执行上下文</span><br><span class="hljs-keyword">var</span> a = <span class="hljs-number">10</span><br><span class="hljs-keyword">var</span> bar = <span class="hljs-keyword">function</span> (<span class="hljs-params">x</span>) &#123;<br>  <span class="hljs-keyword">var</span> b = <span class="hljs-number">5</span><br>  <span class="hljs-title function_">foo</span>(x + b)   <span class="hljs-comment">//3. 进入foo执行上下文           </span><br>&#125;<br><span class="hljs-keyword">var</span> foo = <span class="hljs-keyword">function</span> (<span class="hljs-params">y</span>) &#123;<br>  <span class="hljs-keyword">var</span> c = <span class="hljs-number">5</span><br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a + c + y)<br>&#125;<br><span class="hljs-title function_">bar</span>(<span class="hljs-number">10</span>) <span class="hljs-comment">//2. 进入bar函数执行上下文</span><br></code></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//栗子</span><br>&lt;!--<br><span class="hljs-number">1.</span> 依次输出什么?<br><span class="hljs-attr">gb</span>: <span class="hljs-literal">undefined</span><br><span class="hljs-attr">fb</span>: <span class="hljs-number">1</span><br><span class="hljs-attr">fb</span>: <span class="hljs-number">2</span><br><span class="hljs-attr">fb</span>: <span class="hljs-number">3</span><br><span class="hljs-attr">fe</span>: <span class="hljs-number">3</span><br><span class="hljs-attr">fe</span>: <span class="hljs-number">2</span><br><span class="hljs-attr">fe</span>: <span class="hljs-number">1</span><br><span class="hljs-attr">ge</span>: <span class="hljs-number">1</span><br><span class="hljs-number">2.</span> 整个过程中产生了几个执行上下文?  <span class="hljs-number">5</span><br>--&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;gb: &#x27;</span>+ i)</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">var</span> i = <span class="hljs-number">1</span></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-title function_">foo</span>(<span class="hljs-number">1</span>)</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">function</span> <span class="hljs-title function_">foo</span>(<span class="hljs-params">i</span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-keyword">if</span> (i == <span class="hljs-number">4</span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">    <span class="hljs-keyword">return</span></span></span><br><span class="language-javascript"><span class="language-xml">  &#125;</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fb:&#x27;</span> + i)</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-title function_">foo</span>(i + <span class="hljs-number">1</span>) <span class="hljs-comment">//递归调用: 在函数内部调用自己</span></span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fe:&#x27;</span> + i) <span class="hljs-comment">//出栈 所以会 3 2 1这样的结果</span></span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;ge: &#x27;</span> + i)</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure>

<h3 id="2-4-相关的问题"><a href="#2-4-相关的问题" class="headerlink" title="2.4 相关的问题"></a>2.4 相关的问题</h3><blockquote>
<p><code>函数提升优先级高于变量提升,且不会被变量声明覆盖,但是会被变量赋值覆盖</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*</span><br><span class="hljs-comment">测试题1:  先执行变量提升, 再执行函数提升</span><br><span class="hljs-comment"></span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">a</span>(<span class="hljs-params"></span>) &#123;&#125;<br><span class="hljs-keyword">var</span> a<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-keyword">typeof</span> a) <span class="hljs-comment">// &#x27;function&#x27;</span><br><br><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">测试题2:</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">if</span> (!(b <span class="hljs-keyword">in</span> <span class="hljs-variable language_">window</span>)) &#123;<br><span class="hljs-keyword">var</span> b = <span class="hljs-number">1</span><br>&#125;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b) <span class="hljs-comment">// undefined</span><br><br><span class="hljs-comment">/*</span><br><span class="hljs-comment">测试题3:</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">var</span> c = <span class="hljs-number">1</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">c</span>(<span class="hljs-params">c</span>) &#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(c)<br><span class="hljs-keyword">var</span> c = <span class="hljs-number">3</span> <span class="hljs-comment">//与此行无关</span><br>&#125;<br><span class="hljs-title function_">c</span>(<span class="hljs-number">2</span>) <span class="hljs-comment">// 报错  c is not a function</span><br></code></pre></td></tr></table></figure>
</blockquote>
<h2 id="3-作用域与作用域链"><a href="#3-作用域与作用域链" class="headerlink" title="3. 作用域与作用域链"></a>3. 作用域与作用域链</h2><h3 id="3-1作用域"><a href="#3-1作用域" class="headerlink" title="3.1作用域"></a>3.1作用域</h3><blockquote>
<p>理解: 就是一块”地盘”, 一个代码段所在的区域 , 它是静态的(相对于上下文对象), 在编写代码时就确定了</p>
<p>分类: 全局作用域 函数作用域  没有块作用域(ES6有了)   –&gt;(java语言也有)</p>
<p>作用: 隔离变量，不同作用域下同名变量不会有冲突</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">/*  //没块作用域</span><br><span class="hljs-comment">if(true) &#123; var c = 3 &#125;</span><br><span class="hljs-comment">console.log(c)</span><br><span class="hljs-comment">*/</span><br><span class="hljs-keyword">var</span> a = <span class="hljs-number">10</span>,<br>  b = <span class="hljs-number">20</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params">x</span>) &#123;<br>  <span class="hljs-keyword">var</span> a = <span class="hljs-number">100</span>, c = <span class="hljs-number">300</span>;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;fn()&#x27;</span>, a, b, c, x) <span class="hljs-comment">//100 20 300 10</span><br>  <span class="hljs-keyword">function</span> <span class="hljs-title function_">bar</span>(<span class="hljs-params">x</span>) &#123;<br>    <span class="hljs-keyword">var</span> a = <span class="hljs-number">1000</span>, d = <span class="hljs-number">400</span><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;bar()&#x27;</span>, a, b, c, d, x)<br>  &#125;<br>  <span class="hljs-title function_">bar</span>(<span class="hljs-number">100</span>)<span class="hljs-comment">//1000 20 300 400 100</span><br>  <span class="hljs-title function_">bar</span>(<span class="hljs-number">200</span>)<span class="hljs-comment">//1000 20 300 400 200</span><br>&#125;<br><span class="hljs-title function_">fn</span>(<span class="hljs-number">10</span>)<br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="3-2-作用域与执行上下文的区别与联系"><a href="#3-2-作用域与执行上下文的区别与联系" class="headerlink" title="3.2 作用域与执行上下文的区别与联系"></a>3.2 作用域与执行上下文的区别与联系</h3><blockquote>
<p>区别1: </p>
<p>全局作用域之外，每个函数都会创建自己的作用域，<code>作用域在函数定义时就已经确定了。而不是在函数调用时</code></p>
<p>全局执行上下文环境是在全局作用域确定之后, js代码马上执行之前创建</p>
<p>函数执行上下文是在调用函数时, 函数体代码执行之前创建</p>
<p>区别2:</p>
<p>作用域是静态的, 只要函数定义好了就一直存在, 且不会再变化</p>
<p>执行上下文是动态的, 调用函数时创建, 函数调用结束时就会自动释放</p>
<p>联系:</p>
<p>执行上下文(对象)是从属于所在的作用域</p>
<p>全局上下文环境&#x3D;&#x3D;&gt;全局作用域</p>
<p>函数上下文环境&#x3D;&#x3D;&gt;对应的函数使用域</p>
</blockquote>
<h3 id="3-3-作用域链"><a href="#3-3-作用域链" class="headerlink" title="3.3 作用域链"></a>3.3 作用域链</h3><blockquote>
<p>理解:多个上下级关系的作用域形成的链, 它的方向是从下向上的(从内到外)  查找变量时就是沿着作用域链来查找的</p>
<p>查找一个变量的查找规则: </p>
<p>在当前作用域下的执行上下文中查找对应的属性, 如果有直接返回, 否则进入2</p>
<p>在上一级作用域的执行上下文中查找对应的属性, 如果有直接返回, 否则进入3</p>
<p>再次执行2的相同操作, 直到全局作用域, 如果还找不到就抛出找不到的异常</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> a = <span class="hljs-number">1</span><br> <span class="hljs-keyword">function</span> <span class="hljs-title function_">fn1</span>(<span class="hljs-params"></span>) &#123;<br>   <span class="hljs-keyword">var</span> b = <span class="hljs-number">2</span><br>   <span class="hljs-keyword">function</span> <span class="hljs-title function_">fn2</span>(<span class="hljs-params"></span>) &#123;<br>     <span class="hljs-keyword">var</span> c = <span class="hljs-number">3</span><br>     <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(c)<br>     <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b)<br>     <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a)<br>     <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(d)<br>   &#125;<br>   <span class="hljs-title function_">fn2</span>()<br> &#125;<br> <span class="hljs-title function_">fn1</span>()<br></code></pre></td></tr></table></figure>
</blockquote>
<h3 id="3-4-相关问题"><a href="#3-4-相关问题" class="headerlink" title="3.4 相关问题"></a>3.4 相关问题</h3><blockquote>
<p>作用域在函数定义时就已经确定了。而不是在函数调用时</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) &#123; <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(x); &#125;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">show</span>(<span class="hljs-params">f</span>) &#123;<br><span class="hljs-keyword">var</span> x = <span class="hljs-number">20</span>;<br><span class="hljs-title function_">f</span>();<br>&#125;<br><span class="hljs-title function_">show</span>(fn); <span class="hljs-comment">//输出10</span><br></code></pre></td></tr></table></figure>

<p>对象变量不能产生局部作用域</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">var</span> fn = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(fn)<br>&#125;<br><span class="hljs-title function_">fn</span>()<br><br><span class="hljs-keyword">var</span> obj = &#123; <span class="hljs-comment">//对象变量不能产生局部作用域,所以会找到全局去,导致报错</span><br><span class="hljs-attr">fn2</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(fn2)<br><span class="hljs-comment">//console.log(this.fn2)</span><br>&#125;<br>&#125;<br>obj.<span class="hljs-title function_">fn2</span>()<br></code></pre></td></tr></table></figure>
</blockquote>
<h2 id="4-闭包"><a href="#4-闭包" class="headerlink" title="4. 闭包"></a>4. 闭包</h2><blockquote>
<p>一个函数和对其周围状态（<strong>lexical environment，词法环境</strong>）的引用捆绑在一起（或者说函数被引用包围），这样的组合就是<strong>闭包</strong>（<strong>closure</strong>）。也就是说，闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中，每当创建一个函数，闭包就会在函数创建的同时被创建出来。</p>
</blockquote>
<h3 id="4-1-引出闭包概念"><a href="#4-1-引出闭包概念" class="headerlink" title="4.1 引出闭包概念"></a>4.1 引出闭包概念</h3><h4 id="4-1-1-错误场景"><a href="#4-1-1-错误场景" class="headerlink" title="4.1.1 错误场景"></a>4.1.1 错误场景</h4><blockquote>
<p>需求: <code>点击某个按钮, 提示&quot;点击的是第n个按钮&quot;</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs js">&lt;button&gt;测试<span class="hljs-number">1</span>&lt;/button&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>&lt;!--<br>需求: 点击某个按钮, 提示<span class="hljs-string">&quot;点击的是第n个按钮&quot;</span><br>--&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">var</span> btns = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementsByTagName</span>(<span class="hljs-string">&#x27;button&#x27;</span>)</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//注意[btns]不是一个数组,它是一个伪数组</span></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//每次获取[btns.length]其实都是需要进行计算的(因为它是伪数组)</span></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//所以为了性能更好,在此处赋值,就只需要计算一次</span></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>,length=btns.<span class="hljs-property">length</span>; i &lt; length; i++) &#123;</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">var</span> btn = btns[i]</span></span><br><span class="language-javascript"><span class="language-xml">btn.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;  <span class="hljs-comment">//遍历加监听</span></span></span><br><span class="language-javascript"><span class="language-xml"> <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;第&#x27;</span>+(i+<span class="hljs-number">1</span>)+<span class="hljs-string">&#x27;个&#x27;</span>)     <span class="hljs-comment">//结果 全是[4]</span></span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>   <br></code></pre></td></tr></table></figure>

<p>此处错误是,直接修改并使用全局变量[<code>i</code>],导致for循环结束后,所有点击按钮绑定的弹窗值都是[<code>i+1</code>]</p>
<p>随后调用时,都会找到[<code>i</code>]这个变量,但是此时i&#x3D;&#x3D;3,所以所有结果都是4</p>
</blockquote>
<h4 id="4-1-2-将变量挂载到自身来解决"><a href="#4-1-2-将变量挂载到自身来解决" class="headerlink" title="4.1.2 将变量挂载到自身来解决"></a>4.1.2 将变量挂载到自身来解决</h4><blockquote>
<p>解决方式:将btn所对应的下标保存在btn上</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs js">&lt;button&gt;测试<span class="hljs-number">1</span>&lt;/button&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>&lt;!--<br>需求: 点击某个按钮, 提示<span class="hljs-string">&quot;点击的是第n个按钮&quot;</span><br>--&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">var</span> btns = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementsByTagName</span>(<span class="hljs-string">&#x27;button&#x27;</span>)</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>,length=btns.<span class="hljs-property">length</span>; i &lt; length; i++) &#123;</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">var</span> btn = btns[i]</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//将btn所对应的下标保存在btn上</span></span></span><br><span class="language-javascript"><span class="language-xml">btn.<span class="hljs-property">index</span> = i</span></span><br><span class="language-javascript"><span class="language-xml">btn.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;  <span class="hljs-comment">//遍历加监听</span></span></span><br><span class="language-javascript"><span class="language-xml"> <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;第&#x27;</span>+(i+<span class="hljs-number">1</span>)+<span class="hljs-string">&#x27;个&#x27;</span>)     <span class="hljs-comment">//结果 全是[4]</span></span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>    <br></code></pre></td></tr></table></figure>
</blockquote>
<h4 id="4-1-3-利用闭包"><a href="#4-1-3-利用闭包" class="headerlink" title="4.1.3  利用闭包"></a>4.1.3  利用闭包</h4><p>利用闭包知识点解决,引出下方知识点,不懂的可以带着疑问继续往下看</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs js">&lt;body&gt;<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span>测试3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//利用闭包</span></span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>,length=btns.<span class="hljs-property">length</span>; i &lt; length; i++) &#123;</span></span><br><span class="language-javascript"><span class="language-xml"><span class="hljs-comment">//此处的j是局部的,它将传入的[i]存入局部的[j]中,这样就能实现效果 </span></span></span><br><span class="language-javascript"><span class="language-xml">(<span class="hljs-keyword">function</span> (<span class="hljs-params">j</span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml"> <span class="hljs-keyword">var</span> btn = btns[j]</span></span><br><span class="language-javascript"><span class="language-xml"> btn.<span class="hljs-property">onclick</span> = <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123;</span></span><br><span class="language-javascript"><span class="language-xml">   <span class="hljs-title function_">alert</span>(<span class="hljs-string">&#x27;第&#x27;</span>+(j+<span class="hljs-number">1</span>)+<span class="hljs-string">&#x27;个&#x27;</span>)</span></span><br><span class="language-javascript"><span class="language-xml"> &#125;</span></span><br><span class="language-javascript"><span class="language-xml">&#125;)(i)</span></span><br><span class="language-javascript"><span class="language-xml">&#125;</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span>  <br>&lt;/body&gt;<br></code></pre></td></tr></table></figure>

<h3 id="4-2举个闭包栗子分析理解"><a href="#4-2举个闭包栗子分析理解" class="headerlink" title="4.2举个闭包栗子分析理解"></a>4.2举个闭包栗子分析理解</h3><blockquote>
<p>按照上方 [<code>4</code>]代码举例分析流程的方式 来尝试理解<code>闭包</code>概念</p>
<p>提前给出一个闭包栗子进行分析,先看看发生什么,再去看它的概念进行印证,相信我,你会有种拨开迷雾的感受</p>
</blockquote>
<h4 id="4-2-1-正确的理解"><a href="#4-2-1-正确的理解" class="headerlink" title="4.2.1 正确的理解"></a>4.2.1 正确的理解</h4><blockquote>
<ol>
<li>counter是全局执行上下文的一部分吗?</li>
</ol>
<ul>
<li>尝试 console.log(counter)，得到undefined的结果,显然不是这样的。</li>
</ul>
<ol start="2">
<li>也许，当你调用increment时，它会以某种方式返回它创建的函数(createCounter)?</li>
</ol>
<ul>
<li>这怎么可能呢?变量increment包含函数定义，而不是函数的来源，显然也不是这样的。</li>
</ul>
<ol start="3">
<li>所以一定有另一种机制。<strong>闭包</strong>，我们终于找到了，丢失的那块。</li>
</ol>
<ul>
<li>**-<code>它是这样工作的，无论何时声明新函数并将其赋值给变量，都要存储函数定义和闭包。闭包包含在函数创建时作用域中的所有变量，它类似于背包。函数定义附带一个小背包，它的包中存储了函数定义创建时作用域中的所有变</code> **</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-number">1</span>: <span class="hljs-keyword">function</span> <span class="hljs-title function_">createCounter</span>(<span class="hljs-params"></span>) &#123;<br><span class="hljs-number">2</span>:   <span class="hljs-keyword">let</span> counter = <span class="hljs-number">0</span><br><span class="hljs-number">3</span>:   <span class="hljs-keyword">const</span> myFunction = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) &#123;<br><span class="hljs-number">4</span>:     counter = counter + <span class="hljs-number">1</span><br><span class="hljs-number">5</span>:     <span class="hljs-keyword">return</span> counter<br><span class="hljs-number">6</span>:   &#125;<br><span class="hljs-number">7</span>:   <span class="hljs-keyword">return</span> myFunction<br><span class="hljs-number">8</span>: &#125;<br><span class="hljs-number">9</span>: <span class="hljs-keyword">const</span> increment = <span class="hljs-title function_">createCounter</span>()<br><span class="hljs-number">10</span>: <span class="hljs-keyword">const</span> c1 = <span class="hljs-title function_">increment</span>()<br><span class="hljs-number">11</span>: <span class="hljs-keyword">const</span> c2 = <span class="hljs-title function_">increment</span>()<br><span class="hljs-number">12</span>: <span class="hljs-keyword">const</span> c3 = <span class="hljs-title function_">increment</span>()<br><span class="hljs-number">13</span>: <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;example increment&#x27;</span>, c1, c2, c3)<br></code></pre></td></tr></table></figure>

<p>现在，我们已经从前几个示例中掌握了它的诀窍，让我们按照预期的方式快速执行它：  (<code>错误的流程理解,故意按照正常的逻辑流程走,做印证</code>)</p>
<ol>
<li>同上，第<code>1-8</code>行。我们在全局执行上下文中创建了一个新的变量<code>createCounter</code>，它得到了指定的函数定义。</li>
<li>同上，第<code>9</code>行。</li>
</ol>
<ul>
<li>我们在全局执行上下文中声明了一个名为<code>increment</code>的新变量。</li>
<li>我们需要调用<code>createCounter</code>函数并将其返回值赋给<code>increment</code>变量。</li>
</ul>
<ol start="3">
<li>同上，第<code>1-8</code>行。调用函数，创建新的本地执行上下文。</li>
</ol>
<ul>
<li>第<code>2</code>行。在本地执行上下文中，声明一个名为<code>counter</code>的新变量并赋值为 <code>0</code> 。</li>
<li>第<code>3-6</code>行。声明一个名为<code>myFunction</code>的新变量，变量在本地执行上下文中声明,变量的内容是另一个函数定义。如第<code>4</code>行和第<code>5</code>行所定义，现在我们还创建了一个闭包，并将其作为函数定义的一部分。闭包包含作用域中的变量，在本例中是变量<code>counter</code>(值为<code>0</code>)。</li>
<li>第<code>7</code>行。返回<code>myFunction</code>变量的内容,删除本地执行上下文。<code>myFunction</code>和<code>counter</code>不再存在。控制权交给了调用上下文，我们返回函数定义和它的闭包，闭包中包含了创建它时在作用域内的变量。</li>
</ul>
<ol start="4">
<li>回到第<code>9</code>行。</li>
</ol>
<ul>
<li>在调用上下文(全局执行上下文)中，<code>createCounter</code>返回的值被指定为<code>increment</code></li>
<li>变量<code>increment</code>现在包含一个函数定义(和闭包),由createCounter返回的函数定义,它不再标记为<code>myFunction</code>，但它的定义是相同的,在全局上下文中，称为<code>increment</code>。</li>
</ul>
<ol start="5">
<li>第<code>10</code>行。声明一个新变量<code>c1</code>。</li>
</ol>
<ul>
<li>继续第<code>10</code>行。查找变量<code>increment</code>，它是一个函数，调用它。它包含前面返回的函数定义,如第<code>4-5</code>行所定义的。(<code>它还有一个带有变量的闭包</code>)。</li>
<li>创建一个新的执行上下文，没有参数，开始执行函数。</li>
</ul>
<ol start="6">
<li>第<code>4</code>行。[<code>counter = counter + 1</code>]，寻找变量 [<code>counter</code>]，<code>在查找本地或全局执行上下文之前，让我们检查一下闭包</code>，瞧，闭包包含一个名为[<code>counter</code>]的变量，其值为<code>0</code>。在第<code>4</code>行表达式之后，它的值被设置为<code>1</code>。它再次被储存在闭包里，闭包现在包含值为<code>1</code>的变量 [<code>counter</code>]。</li>
<li>第<code>5</code>行。我们返回<code>counter的值</code>，销毁本地执行上下文。</li>
<li>回到第<code>10</code>行。返回值<code>1</code>被赋给变量<code>c1</code>。</li>
<li>第<code>11</code>行。我们重复步骤<code>10-14</code>。这一次，在闭包中此时变量<code>counter</code>的值是1。它在第<code>12</code>行设置的，它的值被递增并以<code>2</code>的形式存储在递增函数的闭包中,<code>c2</code>被赋值为<code>2</code>。</li>
<li>第<code>12</code>行。重复步骤<code>10-14</code>行,<code>c3</code>被赋值为3。</li>
<li>第13行。我们打印变量<code>c1 c2</code>和<code>c3</code>的值。</li>
</ol>
<p>** <code>你此时可能会问，是否有任何函数具有闭包，甚至是在全局范围内创建的函数?</code> **</p>
<blockquote>
<p>答案是肯定的。在全局作用域中创建的函数创建闭包，但是由于这些函数是在全局作用域中创建的，所以它们可以访问全局作用域中的所有变量，闭包的概念并不重要。</p>
</blockquote>
<blockquote>
<p>但当函数返回函数时，闭包的概念就变得更加重要了。返回的函数可以访问不属于全局作用域的变量，但它们仅存在于其闭包中。</p>
</blockquote>
</blockquote>
<h3 id="4-3-常见的闭包"><a href="#4-3-常见的闭包" class="headerlink" title="4.3 常见的闭包"></a>4.3 常见的闭包</h3><h4 id="4-3-1-将函数作为另一个函数的返回值"><a href="#4-3-1-将函数作为另一个函数的返回值" class="headerlink" title="4.3.1  将函数作为另一个函数的返回值"></a>4.3.1  将函数作为另一个函数的返回值</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">// 1. 将函数作为另一个函数的返回值</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn1</span>(<span class="hljs-params"></span>) &#123;<br><span class="hljs-keyword">var</span> a = <span class="hljs-number">2</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn2</span>(<span class="hljs-params"></span>) &#123;<br> a++<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a)<br>&#125;<br><span class="hljs-keyword">return</span> fn2<br>&#125;<br><span class="hljs-keyword">var</span> f = <span class="hljs-title function_">fn1</span>()<br><span class="hljs-title function_">f</span>() <span class="hljs-comment">// 3</span><br><span class="hljs-title function_">f</span>() <span class="hljs-comment">// 4</span><br></code></pre></td></tr></table></figure>

<h4 id="4-3-2-将函数作为实参传递给另一个函数调用"><a href="#4-3-2-将函数作为实参传递给另一个函数调用" class="headerlink" title="4.3.2 将函数作为实参传递给另一个函数调用"></a>4.3.2 将函数作为实参传递给另一个函数调用</h4><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs stylus"><span class="hljs-comment">// 2. 将函数作为实参传递给另一个函数调用</span><br>function <span class="hljs-built_in">showDelay</span>(msg, time) &#123;<br><span class="hljs-function"><span class="hljs-title">setTimeout</span><span class="hljs-params">(function ()</span></span> &#123;<br> <span class="hljs-built_in">alert</span>(msg)<br>&#125;, time)<br>&#125;<br><span class="hljs-function"><span class="hljs-title">showDelay</span><span class="hljs-params">(<span class="hljs-string">&#x27;atguigu&#x27;</span>, <span class="hljs-number">2000</span>)</span></span><br></code></pre></td></tr></table></figure>

<h3 id="4-4-闭包的作用"><a href="#4-4-闭包的作用" class="headerlink" title="4.4 闭包的作用"></a>4.4 闭包的作用</h3><blockquote>
<ol>
<li>使用函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期)</li>
<li>让函数外部可以操作(读写)到函数内部的数据(变量&#x2F;函数)</li>
</ol>
<p>问题:</p>
<div class="code-wrapper"><pre><code class="hljs">  1. 函数执行完后, 函数内部声明的局部变量是否还存在? 
     -  一般是不存在, 存在于闭中的变量才可能存在
  2. 在函数外部能直接访问函数内部的局部变量吗? 
     - 不能, 但我们可以通过闭包让外部操作它
</code></pre></div>
</blockquote>
<h3 id="4-5-闭包的生命周期"><a href="#4-5-闭包的生命周期" class="headerlink" title="4.5 闭包的生命周期"></a>4.5 闭包的生命周期</h3><blockquote>
<ol>
<li>产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)</li>
<li>死亡: 在嵌套的内部函数成为垃圾对象时</li>
</ol>
<ul>
<li><p>即没有人指向它时死亡,通常置为[<code>null</code>],当然指向其他也行,但不安全(容易污染变量)</p>
</li>
<li><p>&#96;&#96;&#96;js<br>&#x2F;&#x2F;闭包的生命周期<br>function fn1() {<br>   &#x2F;&#x2F;此时闭包就已经产生了(函数提升,实际上[fn2]提升到了第一行, 内部函数对象已经创建了)<br>   var a &#x3D; 2<br>   function fn2 () { &#x2F;&#x2F;如果时[let fn2&#x3D;function(){}],那么在这行才会产生闭包<br> a++<br> console.log(a)<br>   }<br>   return fn2<br> }<br> var f &#x3D; fn1()<br> f() &#x2F;&#x2F; 3<br> f() &#x2F;&#x2F; 4<br> f &#x3D; null &#x2F;&#x2F;闭包死亡(包含闭包的函数对象成为垃圾对象)</p>
<figure class="highlight reasonml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><code class="hljs reasonml"><br>    <br><br>### <span class="hljs-number">4.6</span> 闭包的应用<br><br>闭包的应用 : 定义JS模块<span class="hljs-operator"></span><br><span class="hljs-operator"></span><br><span class="hljs-operator"> * </span>具有特定功能的js文件<span class="hljs-operator"></span><br><span class="hljs-operator"> * </span>将所有的数据和功能都封装在一个函数内部(私有的)<span class="hljs-operator"></span><br><span class="hljs-operator"> * </span>只向外暴露一个包信n个方法的对象或函数<span class="hljs-operator"></span><br><span class="hljs-operator"> * </span>模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能<br><br><span class="hljs-number">1.</span> 模块定义:<br><br><span class="hljs-number">2.</span> ```js<br>   <span class="hljs-comment">//myModule.js</span><br>   <span class="hljs-keyword">function</span> my<span class="hljs-constructor">Module()</span> &#123;<br>     <span class="hljs-comment">//私有数据</span><br>     var msg = &#x27;My atguigu&#x27;<br>     <span class="hljs-comment">//操作数据的函数</span><br>     <span class="hljs-keyword">function</span> <span class="hljs-keyword">do</span><span class="hljs-constructor">Something()</span> &#123;<br>       console.log(&#x27;<span class="hljs-keyword">do</span><span class="hljs-constructor">Something()</span> &#x27;+msg.<span class="hljs-keyword">to</span><span class="hljs-constructor">UpperCase()</span>)<br>     &#125;<br>     <span class="hljs-keyword">function</span> doOtherthing <span class="hljs-literal">()</span> &#123;<br>       console.log(&#x27;<span class="hljs-keyword">do</span><span class="hljs-constructor">Otherthing()</span> &#x27;+msg.<span class="hljs-keyword">to</span><span class="hljs-constructor">LowerCase()</span>)<br>     &#125;<br>   <br>     <span class="hljs-comment">//向外暴露对象(给外部使用的方法)</span><br>     return &#123;<br>       doSomething: doSomething,<br>       doOtherthing: doOtherthing<br>     &#125;<br>   &#125;<br>   <br>   -----------------------------------------------------------------<br>   <span class="hljs-comment">// myModule2.js   </span><br>   (<span class="hljs-keyword">function</span> <span class="hljs-literal">()</span> &#123;<br>     <span class="hljs-comment">//私有数据</span><br>     var msg = &#x27;My atguigu&#x27;<br>     <span class="hljs-comment">//操作数据的函数</span><br>     <span class="hljs-keyword">function</span> <span class="hljs-keyword">do</span><span class="hljs-constructor">Something()</span> &#123;<br>       console.log(&#x27;<span class="hljs-keyword">do</span><span class="hljs-constructor">Something()</span> &#x27;+msg.<span class="hljs-keyword">to</span><span class="hljs-constructor">UpperCase()</span>)<br>     &#125;<br>     <span class="hljs-keyword">function</span> doOtherthing <span class="hljs-literal">()</span> &#123;<br>       console.log(&#x27;<span class="hljs-keyword">do</span><span class="hljs-constructor">Otherthing()</span> &#x27;+msg.<span class="hljs-keyword">to</span><span class="hljs-constructor">LowerCase()</span>)<br>     &#125;<br>   <br>     <span class="hljs-comment">//向外暴露对象(给外部使用的方法)</span><br>     window.myModule2 = &#123;<br>       doSomething: doSomething,<br>       doOtherthing: doOtherthing<br>     &#125;<br>   &#125;)<span class="hljs-literal">()</span>    <br>   <br></code></pre></td></tr></table></figure></li>
</ul>
<p>   模块的调用</p>
   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//调用示例</span><br>------------  模块调用<span class="hljs-number">1</span> --------------------------------------------<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;myModule.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-keyword">var</span> <span class="hljs-variable language_">module</span> = <span class="hljs-title function_">myModule</span>()</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-variable language_">module</span>.<span class="hljs-title function_">doSomething</span>()</span></span><br><span class="language-javascript"><span class="language-xml">  <span class="hljs-variable language_">module</span>.<span class="hljs-title function_">doOtherthing</span>()</span></span><br><span class="language-javascript"><span class="language-xml"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br>------------  模块调用<span class="hljs-number">2</span> --------------------------------------------<br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;myModule2.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span></span><br><span class="language-xml">  myModule2.doSomething()</span><br><span class="language-xml">  myModule2.doOtherthing()</span><br><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span><br></code></pre></td></tr></table></figure>

</blockquote>
<h3 id="4-7-闭包的缺点及解决"><a href="#4-7-闭包的缺点及解决" class="headerlink" title="4.7 闭包的缺点及解决"></a>4.7 闭包的缺点及解决</h3><blockquote>
<ol>
<li>缺点:</li>
</ol>
<ul>
<li>函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长</li>
<li>容易造成内存泄露</li>
</ul>
<ol start="2">
<li>解决:</li>
</ol>
<ul>
<li><p>能不用闭包就不用</p>
</li>
<li><p>及时释放</p>
</li>
<li><p>&#96;&#96;&#96;js<br>function fn1() {<br>  var arr &#x3D; new Array(100000)<br>  function fn2() {<br>console.log(arr.length)<br>  }<br>  return fn2<br>}<br>var f &#x3D; fn1()<br>f()<br>f &#x3D; null &#x2F;&#x2F;让内部函数成为垃圾对象–&gt;回收闭包</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs xml"><br>   我还有一个解决方式,调用时直接`f()()`直接运行调用即可--&gt;匿名函数,用完自动就销毁了<br><br>### 4.8 内存溢出与内存泄露<br><br>1. 内存溢出<br><br> * 一种程序运行出现的错误<br> * 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误<br><br>2. 内存泄露<br><br> * 占用的内存没有及时释放<br> * `内存泄露积累多了就容易导致内存溢出`<br> * 常见的内存泄露:<br>   * 意外的全局变量<br>   * 没有及时清理的计时器或回调函数<br>   * 闭包<br><br>```js<br><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text/javascript&quot;</span>&gt;</span><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-comment">// 1. 内存溢出</span></span><br><span class="language-javascript"><span class="hljs-keyword">var</span> obj = &#123;&#125;</span><br><span class="language-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">10000</span>; i++) &#123;</span><br><span class="language-javascript">  obj[i] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Array</span>(<span class="hljs-number">10000000</span>)</span><br><span class="language-javascript">  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;-----&#x27;</span>)</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-comment">// 2. 内存泄露</span></span><br><span class="language-javascript">  <span class="hljs-comment">// 意外的全局变量</span></span><br><span class="language-javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn</span>(<span class="hljs-params"></span>) &#123;</span><br><span class="language-javascript">  a = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Array</span>(<span class="hljs-number">10000000</span>)  <span class="hljs-comment">//不使用var let const去承接</span></span><br><span class="language-javascript">  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(a)</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"><span class="hljs-title function_">fn</span>()</span><br><span class="language-javascript"></span><br><span class="language-javascript"> <span class="hljs-comment">// 没有及时清理的计时器或回调函数</span></span><br><span class="language-javascript"><span class="hljs-keyword">var</span> intervalId = <span class="hljs-built_in">setInterval</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) &#123; <span class="hljs-comment">//启动循环定时器后不清理</span></span><br><span class="language-javascript">  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;----&#x27;</span>)</span><br><span class="language-javascript">&#125;, <span class="hljs-number">1000</span>)</span><br><span class="language-javascript"></span><br><span class="language-javascript"><span class="hljs-comment">// clearInterval(intervalId)</span></span><br><span class="language-javascript"></span><br><span class="language-javascript">  <span class="hljs-comment">// 闭包</span></span><br><span class="language-javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fn1</span>(<span class="hljs-params"></span>) &#123;</span><br><span class="language-javascript">  <span class="hljs-keyword">var</span> a = <span class="hljs-number">4</span></span><br><span class="language-javascript">  <span class="hljs-keyword">function</span> <span class="hljs-title function_">fn2</span>(<span class="hljs-params"></span>) &#123;</span><br><span class="language-javascript">    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(++a)</span><br><span class="language-javascript">  &#125;</span><br><span class="language-javascript">  <span class="hljs-keyword">return</span> fn2</span><br><span class="language-javascript">&#125;</span><br><span class="language-javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-title function_">fn1</span>()</span><br><span class="language-javascript"><span class="hljs-title function_">f</span>()</span><br><span class="language-javascript"><span class="hljs-comment">// f = null</span></span><br><span class="language-javascript"></span><br><span class="language-javascript"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span><br></code></pre></td></tr></table></figure></li>
</ul>
</blockquote>
<blockquote>
<p>不使用let const var等去声明,实际上是挂载到[<code>window</code>]上的,所以导致内存泄露</p>
</blockquote>
<h3 id="4-9-相关的问题"><a href="#4-9-相关的问题" class="headerlink" title="4.9 相关的问题"></a>4.9 相关的问题</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-comment">//代码片段一  --&gt;没有产生闭包:因为内部函数没有调用外部变量</span><br><span class="hljs-keyword">var</span> name = <span class="hljs-string">&quot;The Window&quot;</span>;<br><span class="hljs-keyword">var</span> object = &#123;<br>name : <span class="hljs-string">&quot;My Object&quot;</span>,<br>getNameFunc : <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br><span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br> <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">name</span>;<br>&#125;;<br>&#125;<br>&#125;;<br><span class="hljs-title function_">alert</span>(object.<span class="hljs-title function_">getNameFunc</span>()());  <span class="hljs-comment">//?  the window</span><br><span class="hljs-comment">//函数体的this是window</span><br><br><span class="hljs-comment">//代码片段二</span><br><span class="hljs-keyword">var</span> name2 = <span class="hljs-string">&quot;The Window&quot;</span>;<br><span class="hljs-keyword">var</span> object2 = &#123;<br>name2 : <span class="hljs-string">&quot;My Object&quot;</span>,<br>getNameFunc : <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br><span class="hljs-comment">//此处的this指向是[getNameFunc],他是对象中的属性,所以this指向就是object</span><br><span class="hljs-keyword">var</span> that = <span class="hljs-variable language_">this</span>;<br><span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)&#123;<br> <span class="hljs-comment">//此处用的是保存的  that</span><br> <span class="hljs-keyword">return</span> that.<span class="hljs-property">name2</span>;<br>&#125;;<br>&#125;<br>&#125;;<br><span class="hljs-title function_">alert</span>(object2.<span class="hljs-title function_">getNameFunc</span>()()); <span class="hljs-comment">//?  my object</span><br></code></pre></td></tr></table></figure>

<blockquote>
<ol>
<li>代码片段一:</li>
</ol>
<ul>
<li>函数体的<code>this</code>指向是[<code>window</code>]</li>
<li>没有产生闭包:因为内部函数没有调用外部变量</li>
</ul>
<ol start="2">
<li>代码片段二为何指向是对象?</li>
</ol>
<ul>
<li>this指向是调用它的[<code>getNameFunc</code>],他是对象中的属性,所以this指向就是object</li>
<li>产生了闭包</li>
</ul>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs js"><span class="hljs-keyword">function</span> <span class="hljs-title function_">fun</span>(<span class="hljs-params">n,o</span>) &#123;<br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(o)<br><span class="hljs-keyword">return</span> &#123;<br><span class="hljs-attr">fun</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params">m</span>)&#123;<br> <span class="hljs-keyword">return</span> <span class="hljs-title function_">fun</span>(m,n)<br>&#125;<br>&#125;<br>&#125;<br><span class="hljs-keyword">var</span> a = <span class="hljs-title function_">fun</span>(<span class="hljs-number">0</span>) <span class="hljs-comment">//undefined</span><br>a.<span class="hljs-title function_">fun</span>(<span class="hljs-number">1</span>)  <span class="hljs-comment">//0</span><br>a.<span class="hljs-title function_">fun</span>(<span class="hljs-number">2</span>)  <span class="hljs-comment">//0	</span><br>a.<span class="hljs-title function_">fun</span>(<span class="hljs-number">3</span>)  <span class="hljs-comment">//0</span><br><br><span class="hljs-keyword">var</span> b = <span class="hljs-title function_">fun</span>(<span class="hljs-number">0</span>).<span class="hljs-title function_">fun</span>(<span class="hljs-number">1</span>).<span class="hljs-title function_">fun</span>(<span class="hljs-number">2</span>).<span class="hljs-title function_">fun</span>(<span class="hljs-number">3</span>) <span class="hljs-comment">//undefined 0 1 2</span><br><br><span class="hljs-keyword">var</span> c = <span class="hljs-title function_">fun</span>(<span class="hljs-number">0</span>).<span class="hljs-title function_">fun</span>(<span class="hljs-number">1</span>) <span class="hljs-comment">//undefined  0</span><br>c.<span class="hljs-title function_">fun</span>(<span class="hljs-number">2</span>)<span class="hljs-comment">//1 --&gt;经过上方定义后 n固定为1</span><br>c.<span class="hljs-title function_">fun</span>(<span class="hljs-number">3</span>)<span class="hljs-comment">//1 --&gt;此处是陷阱!!!  一直没有改到n,所以一直是1</span><br></code></pre></td></tr></table></figure>


            </div>
            <hr>
            <div>
              <div class="post-metas mb-3">
                
                
              </div>
              <p class="note note-warning">
                <strong>本文作者: </strong><a href="/HexoPage/">xiao_aodi</a> <br>
                <!-- <strong>本文链接: </strong><a href="http://xiao_aodi.gitee.io/hexopage/2022/03/22/JavaScript%E8%BF%9B%E9%98%B6%E5%AD%A6%E4%B9%A0%E7%9A%84%E7%AC%94%E8%AE%B0/">http://xiao_aodi.gitee.io/hexopage/2022/03/22/JavaScript%E8%BF%9B%E9%98%B6%E5%AD%A6%E4%B9%A0%E7%9A%84%E7%AC%94%E8%AE%B0/</a> <br> -->
                <strong>版权声明: </strong>本博客所有文章除特别声明外，均采用 <a target="_blank" href="https://creativecommons.org/licenses/by-sa/4.0/deed.zh" rel="nofollow noopener noopener">CC BY-SA 4.0 协议</a> ，转载请注明出处！
                   </p>
                   

              
                <div class="post-prevnext">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/HexoPage/2022/03/23/JavaScript%E5%AD%A6%E4%B9%A0%E5%B7%A9%E5%9B%BA%E5%9F%BA%E7%A1%80%E5%A4%96%E5%8A%A0%E8%BF%9B%E9%98%B6(%E4%B8%8B)%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86/">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">JavaScript学习巩固基础外加进阶(下)底层原理</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/HexoPage/2022/03/21/js%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86%E7%AC%94%E8%AE%B0/">
                        <span class="hidden-mobile">JavaScript学习笔记（第四部分）总共四部分(完结)</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
    

    
  </main>

  <footer class="text-center mt-5 py-3">
  
   <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a>  
  <!-- 添加网站运行时间 -->
  <div class="footer-content">
    <div>
      <span id="timeDate">载入天数...</span>
      <span id="times">载入时分秒...</span>
      <script>
      var now = new Date();
      function createtime(){
          var grt= new Date("03/10/2022 00:00:00");//此处修改你的建站时间或者网站上线时间
          now.setTime(now.getTime()+250);
          days = (now - grt ) / 1000 / 60 / 60 / 24;
          dnum = Math.floor(days);
          hours = (now - grt ) / 1000 / 60 / 60 - (24 * dnum);
          hnum = Math.floor(hours);
          if(String(hnum).length ==1 ){
              hnum = "0" + hnum;
          }
          minutes = (now - grt ) / 1000 /60 - (24 * 60 * dnum) - (60 * hnum);
          mnum = Math.floor(minutes);
          if(String(mnum).length ==1 ){
                    mnum = "0" + mnum;
          }
          seconds = (now - grt ) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum);
          snum = Math.round(seconds);
          if(String(snum).length ==1 ){
                    snum = "0" + snum;
          }
          document.getElementById("timeDate").innerHTML = "🚀 &nbsp"+dnum+"&nbsp天";  //此次自定义显示内容
          document.getElementById("times").innerHTML = hnum + "&nbsp小时&nbsp" + mnum + "&nbsp分&nbsp" + snum + "&nbsp秒";
      }  //此次自定义显示内容
      setInterval("createtime()",250);
      </script>
    </div>
  </div>
  <!-- 统计访问量信息 -->
  
  <div class="statistics">
    
    

    
      
        <!-- 不蒜子统计PV -->
        <span id="busuanzi_container_site_pv" style="display: none">
            总访问量 
            <span id="busuanzi_value_site_pv"></span>
             次
          </span>
      
      
        <!-- 不蒜子统计UV -->
        <span id="busuanzi_container_site_uv" style="display: none">
            总访客数 
            <span id="busuanzi_value_site_uv"></span>
             人
          </span>
      
    
  </div>


  <!-- 个人和备案信息 -->
  <div>©2022-2023<a target="_blank" rel="noopener" href="https://clearlight.blog.csdn.net/">ClearlightY</a> <a target="_blank" rel="noopener" href="http://beian.miit.gov.cn/">冀ICP备19019307号-2</a></div>
   
  <!-- 备案信息 -->
  <div class="beian">
    <span>
      <a href="http://beian.miit.gov.cn/" target="_blank" rel="nofollow noopener">
        京ICP证123456号
      </a>
    </span>
    
      
        <span>
          <a
            href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=12345678"
            rel="nofollow noopener"
            class="beian-police"
            target="_blank"
          >
            
              <span style="visibility: hidden; width: 0">|</span>
              <img src="/HexoPage/img/police_beian.png" alt="police-icon"/>
            
            <span>京公网安备12345678号</span>
          </a>
        </span>
      
    
  </div>


  
</footer>

<!-- SCRIPTS -->

  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/HexoPage/js/events.js" ></script>
<script  src="/HexoPage/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/HexoPage/js/local-search.js" ></script>





  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
        typing(title);
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/HexoPage/js/boot.js" ></script>




  <!-- SCRIPTS -->
  
  <script  src="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://cdn.jsdelivr.net/npm/nprogress@0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js" ></script>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.min.js" ></script>
<script  src="/HexoPage/js/events.js" ></script>
<script  src="/HexoPage/js/plugins.js" ></script>

<!-- Plugins -->


  <script  src="/HexoPage/js/local-search.js" ></script>





  



  
    <script  src="https://cdn.jsdelivr.net/npm/tocbot@4/dist/tocbot.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3/dist/jquery.fancybox.min.js" ></script>
  
  
    <script  src="https://cdn.jsdelivr.net/npm/anchor-js@4/anchor.min.js" ></script>
  
  
    <script defer src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js" ></script>
  



  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  <script  src="https://cdn.jsdelivr.net/npm/typed.js@2/lib/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var title = document.getElementById('subtitle').title;
      
        typing(title);
      
    })(window, document);
  </script>















<!-- 主题的启动项 保持在最底部 -->
<script  src="/HexoPage/js/boot.js" ></script>


</body>
</html>
